﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;

namespace IPC.Communication.Framework.Core.Net
{
    public class ReadWriteNetHelper
    {
	    public static OperateResult<TimeSpan> Wait(IReadWriteNet readWriteNet, string address, bool waitValue, int readInterval, int waitTimeout)
	    {
		    DateTime now = DateTime.Now;
		    while (true)
		    {
			    OperateResult<bool> operateResult = readWriteNet.ReadBool(address);
			    if (!operateResult.IsSuccess)
			    {
				    return OperateResult.CreateFailedResult<TimeSpan>(operateResult);
			    }
			    if (operateResult.Content == waitValue)
			    {
				    return OperateResult.CreateSuccessResult(DateTime.Now - now);
			    }
			    if (waitTimeout > 0 && (DateTime.Now - now).TotalMilliseconds > (double)waitTimeout)
			    {
				    break;
			    }
			    Thread.Sleep(readInterval);
		    }
		    return new OperateResult<TimeSpan>(StringResources.Language.CheckDataTimeout + waitTimeout.ToString());
	    }

	    public static OperateResult<TimeSpan> Wait(IReadWriteNet readWriteNet, string address, short waitValue, int readInterval, int waitTimeout)
	    {
		    DateTime now = DateTime.Now;
		    while (true)
		    {
			    OperateResult<short> operateResult = readWriteNet.ReadInt16(address);
			    if (!operateResult.IsSuccess)
			    {
				    return OperateResult.CreateFailedResult<TimeSpan>(operateResult);
			    }
			    if (operateResult.Content == waitValue)
			    {
				    return OperateResult.CreateSuccessResult(DateTime.Now - now);
			    }
			    if (waitTimeout > 0 && (DateTime.Now - now).TotalMilliseconds > (double)waitTimeout)
			    {
				    break;
			    }
			    Thread.Sleep(readInterval);
		    }
		    return new OperateResult<TimeSpan>(StringResources.Language.CheckDataTimeout + waitTimeout.ToString());
	    }

	    public static OperateResult<TimeSpan> Wait(IReadWriteNet readWriteNet, string address, ushort waitValue, int readInterval, int waitTimeout)
	    {
		    DateTime now = DateTime.Now;
		    while (true)
		    {
			    OperateResult<ushort> operateResult = readWriteNet.ReadUInt16(address);
			    if (!operateResult.IsSuccess)
			    {
				    return OperateResult.CreateFailedResult<TimeSpan>(operateResult);
			    }
			    if (operateResult.Content == waitValue)
			    {
				    return OperateResult.CreateSuccessResult(DateTime.Now - now);
			    }
			    if (waitTimeout > 0 && (DateTime.Now - now).TotalMilliseconds > (double)waitTimeout)
			    {
				    break;
			    }
			    Thread.Sleep(readInterval);
		    }
		    return new OperateResult<TimeSpan>(StringResources.Language.CheckDataTimeout + waitTimeout.ToString());
	    }

	    public static OperateResult<TimeSpan> Wait(IReadWriteNet readWriteNet, string address, int waitValue, int readInterval, int waitTimeout)
	    {
		    DateTime now = DateTime.Now;
		    while (true)
		    {
			    OperateResult<int> operateResult = readWriteNet.ReadInt32(address);
			    if (!operateResult.IsSuccess)
			    {
				    return OperateResult.CreateFailedResult<TimeSpan>(operateResult);
			    }
			    if (operateResult.Content == waitValue)
			    {
				    return OperateResult.CreateSuccessResult(DateTime.Now - now);
			    }
			    if (waitTimeout > 0 && (DateTime.Now - now).TotalMilliseconds > (double)waitTimeout)
			    {
				    break;
			    }
			    Thread.Sleep(readInterval);
		    }
		    return new OperateResult<TimeSpan>(StringResources.Language.CheckDataTimeout + waitTimeout.ToString());
	    }

	    public static OperateResult<TimeSpan> Wait(IReadWriteNet readWriteNet, string address, uint waitValue, int readInterval, int waitTimeout)
	    {
		    DateTime now = DateTime.Now;
		    while (true)
		    {
			    OperateResult<uint> operateResult = readWriteNet.ReadUInt32(address);
			    if (!operateResult.IsSuccess)
			    {
				    return OperateResult.CreateFailedResult<TimeSpan>(operateResult);
			    }
			    if (operateResult.Content == waitValue)
			    {
				    return OperateResult.CreateSuccessResult(DateTime.Now - now);
			    }
			    if (waitTimeout > 0 && (DateTime.Now - now).TotalMilliseconds > (double)waitTimeout)
			    {
				    break;
			    }
			    Thread.Sleep(readInterval);
		    }
		    return new OperateResult<TimeSpan>(StringResources.Language.CheckDataTimeout + waitTimeout.ToString());
	    }

	    public static OperateResult<TimeSpan> Wait(IReadWriteNet readWriteNet, string address, long waitValue, int readInterval, int waitTimeout)
	    {
		    DateTime now = DateTime.Now;
		    while (true)
		    {
			    OperateResult<long> operateResult = readWriteNet.ReadInt64(address);
			    if (!operateResult.IsSuccess)
			    {
				    return OperateResult.CreateFailedResult<TimeSpan>(operateResult);
			    }
			    if (operateResult.Content == waitValue)
			    {
				    return OperateResult.CreateSuccessResult(DateTime.Now - now);
			    }
			    if (waitTimeout > 0 && (DateTime.Now - now).TotalMilliseconds > (double)waitTimeout)
			    {
				    break;
			    }
			    Thread.Sleep(readInterval);
		    }
		    return new OperateResult<TimeSpan>(StringResources.Language.CheckDataTimeout + waitTimeout.ToString());
	    }

	    public static OperateResult<TimeSpan> Wait(IReadWriteNet readWriteNet, string address, ulong waitValue, int readInterval, int waitTimeout)
	    {
		    DateTime now = DateTime.Now;
		    while (true)
		    {
			    OperateResult<ulong> operateResult = readWriteNet.ReadUInt64(address);
			    if (!operateResult.IsSuccess)
			    {
				    return OperateResult.CreateFailedResult<TimeSpan>(operateResult);
			    }
			    if (operateResult.Content == waitValue)
			    {
				    return OperateResult.CreateSuccessResult(DateTime.Now - now);
			    }
			    if (waitTimeout > 0 && (DateTime.Now - now).TotalMilliseconds > (double)waitTimeout)
			    {
				    break;
			    }
			    Thread.Sleep(readInterval);
		    }
		    return new OperateResult<TimeSpan>(StringResources.Language.CheckDataTimeout + waitTimeout.ToString());
	    }

        //[AsyncStateMachine(typeof(<WaitAsync>d__7))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult<TimeSpan>> WaitAsync(IReadWriteNet readWriteNet, string address, bool waitValue, int readInterval, int waitTimeout)
        //{
        //    <WaitAsync>d__7 stateMachine = new <WaitAsync>d__7();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<TimeSpan>>.Create();
        //    stateMachine.readWriteNet = readWriteNet;
        //    stateMachine.address = address;
        //    stateMachine.waitValue = waitValue;
        //    stateMachine.readInterval = readInterval;
        //    stateMachine.waitTimeout = waitTimeout;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WaitAsync>d__8))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult<TimeSpan>> WaitAsync(IReadWriteNet readWriteNet, string address, short waitValue, int readInterval, int waitTimeout)
        //{
        //    <WaitAsync>d__8 stateMachine = new <WaitAsync>d__8();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<TimeSpan>>.Create();
        //    stateMachine.readWriteNet = readWriteNet;
        //    stateMachine.address = address;
        //    stateMachine.waitValue = waitValue;
        //    stateMachine.readInterval = readInterval;
        //    stateMachine.waitTimeout = waitTimeout;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WaitAsync>d__9))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult<TimeSpan>> WaitAsync(IReadWriteNet readWriteNet, string address, ushort waitValue, int readInterval, int waitTimeout)
        //{
        //    <WaitAsync>d__9 stateMachine = new <WaitAsync>d__9();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<TimeSpan>>.Create();
        //    stateMachine.readWriteNet = readWriteNet;
        //    stateMachine.address = address;
        //    stateMachine.waitValue = waitValue;
        //    stateMachine.readInterval = readInterval;
        //    stateMachine.waitTimeout = waitTimeout;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WaitAsync>d__10))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult<TimeSpan>> WaitAsync(IReadWriteNet readWriteNet, string address, int waitValue, int readInterval, int waitTimeout)
        //{
        //    <WaitAsync>d__10 stateMachine = new <WaitAsync>d__10();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<TimeSpan>>.Create();
        //    stateMachine.readWriteNet = readWriteNet;
        //    stateMachine.address = address;
        //    stateMachine.waitValue = waitValue;
        //    stateMachine.readInterval = readInterval;
        //    stateMachine.waitTimeout = waitTimeout;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WaitAsync>d__11))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult<TimeSpan>> WaitAsync(IReadWriteNet readWriteNet, string address, uint waitValue, int readInterval, int waitTimeout)
        //{
        //    <WaitAsync>d__11 stateMachine = new <WaitAsync>d__11();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<TimeSpan>>.Create();
        //    stateMachine.readWriteNet = readWriteNet;
        //    stateMachine.address = address;
        //    stateMachine.waitValue = waitValue;
        //    stateMachine.readInterval = readInterval;
        //    stateMachine.waitTimeout = waitTimeout;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WaitAsync>d__12))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult<TimeSpan>> WaitAsync(IReadWriteNet readWriteNet, string address, long waitValue, int readInterval, int waitTimeout)
        //{
        //    <WaitAsync>d__12 stateMachine = new <WaitAsync>d__12();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<TimeSpan>>.Create();
        //    stateMachine.readWriteNet = readWriteNet;
        //    stateMachine.address = address;
        //    stateMachine.waitValue = waitValue;
        //    stateMachine.readInterval = readInterval;
        //    stateMachine.waitTimeout = waitTimeout;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WaitAsync>d__13))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult<TimeSpan>> WaitAsync(IReadWriteNet readWriteNet, string address, ulong waitValue, int readInterval, int waitTimeout)
        //{
        //    <WaitAsync>d__13 stateMachine = new <WaitAsync>d__13();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<TimeSpan>>.Create();
        //    stateMachine.readWriteNet = readWriteNet;
        //    stateMachine.address = address;
        //    stateMachine.waitValue = waitValue;
        //    stateMachine.readInterval = readInterval;
        //    stateMachine.waitTimeout = waitTimeout;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}
    }
}
